#ifndef _Message_Process_
#define _Message_Process_
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<time.h>

#include "mytypes.h"
#include "MMSG.h"
#include "DLMAP.h"
#include "FCH.h"
#include "DCD.h"
#include "UCD.h"
#include "ULMAP.h"
#include "RNG.h"


typedef struct Self_CID_List
{	
	uint32 CID;
	enum CID_Type CID_type;
	struct Self_CID_List *next;
}SCID_List;

//------------------------------------------
typedef union Management_MSG_union {
	FCH     *fch    ;
	DCD     *dcd    ;
	DLMAP   *dlmap  ;
	UCD     *ucd    ;
	ULMAP   *ulmap  ;
	RNGRSP  *rngrsp ;
	RNGREQ  *rngreq ;
	CDMACODE *cdmacode;
}MMSG;
typedef struct MsgQueue
{
	uint64 value;
	uint16 length;
	struct MsgQueue *next;
	struct MsgQueue *prev;
}MsgQ;
typedef struct MSG_List_struct
{
	uint16 type ;
	uint16 CID ; 
	union  Management_MSG_union *mmsg ;
	struct MSG_List_struct *next ;
}MsgList;
typedef struct BUFFER_struct
{
	uint8 *buffer;	
	uint32 bitoffset;
	uint8 *base;
	
}BUFFER;




typedef struct MAC_Signaling_Header1
{
	uint32 HT;
	uint32 EC;
	uint32 Type ;
	uint32 Content;
	uint32 CID;
	uint32 HCS;
}SigHeader;

typedef struct G_MACHeader_Type_sturct
{
	uint8 MeshSH;//Mesh SubHeader
	uint8 ARQFBPd;//ARQ FeedBack Payload
	uint8 ExtType;//Extend Type
	uint8 FragSH;//Fragmentation SubHeader
	uint8 PackSH;//Packing SubHeader
	uint8 FBGMSH;//Fast FeedBack Allocation SubHeader;Grant Management SubHeader
}GMHType;

typedef struct Generic_MACHeader_struct
{
	uint32 HT  ;// HT/EC= 0/0:DL and UL with no encryption. 0/1:DL and UL with encryption
	uint32 EC  ;// =1/0:UL signaling type header without data payload. 1/1:compressed dlmap
	uint32 Type;//there are six parameters in this type message
	uint32 ESF ;//1:Extended type 0:non Extended type
	uint32 CI  ;//1:CRC 0:NonCRC 
	uint32 EKS ;//1:Encryption Key 0:non Encryption Key
	int32  LEN ;//total length included the CRC payload
	uint32 CID ;
	uint32 HCS ;//Header Check Sum 
}G_MACHeader;

// -- Fragment subheader -- //
typedef struct Fragment_SubHeader_struct
{
    enum FC Fc;
	uint32  BSN;
	uint32  FSN;
}Frag_SubHeader;


// -- Packing subheader -- //
typedef struct Packing_Subheader_stuct
{
	enum FC Fc;
	uint32	BSN;
	uint32  FSN;
	uint32	Length;	
}Pack_SubHeader;


typedef struct Message_Header_struct
{	
	Pack_SubHeader PSH;
	Frag_SubHeader FSH;
	G_MACHeader GMHeader;
	//added parameters
	uint32 ForARQ;
	uint32 ForExt;
	uint32 CID;
}Header;


typedef struct SlaveDataQueue
{
	uint32 *ptr;
	int length;	
	enum   STATUS status;
	struct SlaveDataQueue *next;
	struct SlaveDataQueue *prev;

}SDQ;

typedef struct MasterDataQueue
{
	uint32 fixVar;
	uint32  isARQ;
	uint32 CID;
	uint32 Qlength;
	int quota;
	struct SlaveDataQueue *dataQ;
	struct MasterDataQueue *next;
}MDQ;


uint32 TT[256];//timer number
uint16 UCD_TLV_Table[256];
uint16 RngRsp_TLV_Table[256];
uint16 RngReq_TLV_Table[256];

void Init_Buffer(BUFFER **);
void Init_MsgQ(MsgQ **);
void Init_Msg_DLMAP(MMSG **);
void Init_SelfCID(SCID_List **);
void Init_DCD_TLV_TABLE();
void Init_UCD_TLV_TABLE();
void InitRngRspTLVTable();
void InitRngReqTLVTable();

BUFFER* FormatMsgQ2Buf(MsgQ *);
void DeFormat2Val(BUFFER **,uint64 *,uint8);

void Form_DLMAP(MMSG **,MsgQ **);
void Form_ULMAP(MMSG **,MsgQ **);

void DeForm_UCD(BUFFER **,UCD **);
void DeForm_DCD(BUFFER **buf_pp,DCD **dcd_pp);
void DeForm_ULMAP(BUFFER **,ULMAP **,SCID_List *);
void DeForm_DLMAP(BUFFER **,DLMAP **,SCID_List *);
void DeFormRNGRSP(BUFFER **buf_pp,RNGRSP **rngrsp);

void Insert_MsgQ_DList(MsgQ **,uint64 ,uint8 );
void Insert_DataQ_DList(SDQ **,uint32 *,uint32 );
MsgList *InsertMsgList(MsgList **,uint16 ,uint16 ,MMSG *);

void Delete_MsgQ_DList(MsgQ *);

void Append_UMPIE_List(ULMAP_IE **,UMP_Ext_DIUC *,uint16 ,uint16 );
void AppendTLV(Msg_TLV **ptr,uint16 type ,uint16 table[],uint64 value);
void Append_PDUQ(MDQ **,SDQ *,uint32 ,uint32 ,uint32 );
MsgList *Append_Msg_List(MsgList **ptr,uint16 type,uint16 cid,MMSG *mmsg);
void Append_SC_CID(SCID_List **ptr,uint32 cid,enum CID_Type cid_type);
void Append_Msg_BP(Msg_BP **ptr,uint16 diuc ,uint16 BP);

uint32 Is_SelfCID(SCID_List *,uint16 );

void AllocUEDDepIE14(UMP_Ext_DIUC **);
void AllocUEDDepIE12(UMP_Ext_DIUC ** );

void Test_DLMAP();
void Test_FCH();
void Test_DCD();
void Test_UCD();
void Test_ULMAP();

void Skip_DeFormat(BUFFER ** ,uint8 );
void PrintMsgVal(char [],char[] ,uint32 );
void PrintMsg(char[] ,char [],char []);
void Form_FCH(MMSG **,MsgQ **);
void Init_Msg_FCH(MMSG **);
void DeForm_FCH(BUFFER **,FCH **);
void PrintSystemTime(char [],uint32  ,char []);
#endif
